package com.yimi.yinhepda.utils;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author 000432
 * @date 2015/8/10
 */
public class BitmapUtils {
  /**
   * @param options 参数
   * @param reqWidth 目标的宽度
   * @param reqHeight 目标的高度
   * @description 计算图片的压缩比率
   */
  private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // 源图片的高度和宽度
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;
    if (height > reqHeight || width > reqWidth) {
      // 计算出实际宽高和目标宽高的比率
      final int halfHeight = height / 2;
      final int halfWidth = width / 2;
      while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
        inSampleSize *= 2;
      }
    }
    return inSampleSize;
  }

  /**
   * @description 通过传入的bitmap，进行压缩，得到符合标准的bitmap
   */
  private static Bitmap createScaleBitmap(Bitmap src, int dstWidth, int dstHeight, int inSampleSize) {
    //如果inSampleSize是2的倍数，也就说这个src已经是我们想要的缩略图了，直接返回即可。
    if (inSampleSize % 2 == 0) {
      return src;
    }
    // 如果是放大图片，filter决定是否平滑，如果是缩小图片，filter无影响，我们这里是缩小图片，所以直接设置为false
    Bitmap dst = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, false);
    if (src != dst) {
      // 如果没有缩放，那么不回收
      src.recycle(); // 释放Bitmap的native像素数组
    }
    return dst;
  }

  /**
   * @description 从Resources中加载图片
   */
  public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
    final BitmapFactory.Options options = new BitmapFactory.Options();
    // 设置成了true,不占用内存，只获取bitmap宽高
    options.inJustDecodeBounds = true;
    // 读取图片长款
    BitmapFactory.decodeResource(res, resId, options);
    // 调用上面定义的方法计算inSampleSize值
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    // 使用获取到的inSampleSize值再次解析图片
    options.inJustDecodeBounds = false;
    // 载入一个稍大的缩略图
    Bitmap src = BitmapFactory.decodeResource(res, resId, options);
    // 进一步得到目标大小的缩略图
    return createScaleBitmap(src, reqWidth, reqHeight, options.inSampleSize);
  }

  /**
   * @description 从SD卡上加载图片
   */
  public static Bitmap decodeSampledBitmapFromFile(String pathName, int reqWidth, int reqHeight) {
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(pathName, options);
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    options.inJustDecodeBounds = false;
    Bitmap src = BitmapFactory.decodeFile(pathName, options);
    return createScaleBitmap(src, reqWidth, reqHeight, options.inSampleSize);
  }

  public static boolean compressBmpToFile(Bitmap bmp, String path) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    //个人喜欢从80开始
    int options = 80;
    bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
    Log.w("compressBmpToFile", "baos.toByteArray().length=" + baos.toByteArray().length);
    while (baos.toByteArray().length / 1024 > 100) {
      baos.reset();
      options -= 10;
      bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
    }
    Log.w("compressBmpToFile", "options=" + options);
    try {
      File file = new File(path);
      FileOutputStream fos = new FileOutputStream(file);
      fos.write(baos.toByteArray());
      fos.flush();
      fos.close();
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }

    return true;
  }

  /**
   * 保存bitmap 到path路径
   */
  public static boolean save(Bitmap mBitmap, String path) {
    File file = new File(path);
    FileOutputStream fos = null;
    try {
      fos = new FileOutputStream(file);
      return mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
    } catch (FileNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } finally {
      if (fos != null) {
        try {
          fos.close();
        } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        fos = null;
      }
    }
    return false;
  }
}
